home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / aplictns / graph.5 < prev    next >
Internet Message Format  |  1989-11-13  |  33KB

  1. Path: xanth!lll-winken!uunet!cs.utexas.edu!think!gem.mps.ohio-state.edu!brutus.cs.uiuc.edu!wuarchive!texbell!texsun!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i208:  graph - plot mathematical functions, Part05/07
  5. Message-ID: <127786@sun.Eng.Sun.COM>
  6. Date: 13 Nov 89 02:32:38 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1070
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: dg3i+@andrew.cmu.edu (David Gay)
  12. Posting-number: Volume 89, Issue 208
  13. Archive-name: applications/graph.5
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    grph.h
  24. #    label.c
  25. #    list.c
  26. #    list.h
  27. #    lmkfile
  28. #    lmko
  29. #    lnk
  30. #    lnko
  31. #    make.shar
  32. #    mv2dir
  33. # This is archive 5 of a 7-part kit.
  34. # This archive created: Sun Nov 12 18:23:31 1989
  35. echo "extracting grph.h"
  36. sed 's/^X//' << \SHAR_EOF > grph.h
  37. X/*
  38. X *                 GRAPH, Version 1.00 - 4 August 1989
  39. X *
  40. X *            Copyright 1989, David Gay. All Rights Reserved.
  41. X *            This software is freely redistrubatable.
  42. X */
  43. X
  44. X/* Routines for handling graphs */
  45. X#ifndef GRPH_H
  46. X#define GRPH_H
  47. X
  48. X#include "list.h"
  49. X#include "user/gadgets.h"
  50. X
  51. X/* Various string lengths */
  52. X#define TITLELEN 80
  53. X#define GNAMELEN 20
  54. X
  55. X/* Store information on each axis */
  56. Xstruct ax {
  57. X    double min, max;
  58. X    double ax, cstep; /* Axes positions, ax is the position of this axis on the
  59. X other */
  60. X                      /* cstep: interval for ticks */
  61. X    int every;        /* Frequency of numbering on ticks */
  62. X    int log;          /* log scale ? */
  63. X};
  64. X
  65. X/* Information on coordinate system */
  66. Xstruct axes {
  67. X    struct ax x, y;
  68. X    double ratio; /* y / x, NOVAL for none (>0 !!) */
  69. X    int polar : 1; /* Not used */
  70. X    int ok : 1;
  71. X};
  72. X
  73. X/* User interface state */
  74. Xstruct state {
  75. X    int select_mode : 1;
  76. X    int mouse : 1;          /* mouse moves expected */
  77. X    double x, y;            /* mouse pos. */
  78. X    struct object *current;
  79. X};
  80. X
  81. X/* All information needed for user interface */
  82. Xstruct io {
  83. X    UWORD nextmenu;            /* For menu selections */
  84. X    struct RWindow *rw;        /* Currently selected output */
  85. X    int dpmx, dpmy;            /* Scale (in dots per meter) of output */
  86. X    struct Window *win;        /* Window, and assoc. info */
  87. X    WORD oldwidth, oldheight;
  88. X    struct Gadget *gadgets;
  89. X    struct Menu *menu;
  90. X    struct Memory *mem;
  91. X    char title[TITLELEN];
  92. X    struct TextFont *digits;   /* Font for displaying digits on graph */
  93. X};
  94. X
  95. X/* A graph, made up from the above components */
  96. X
  97. Xstruct graph {
  98. X    node node;
  99. X    int ok : 1;
  100. X    int saved : 1;
  101. X    char name[GNAMELEN];
  102. X    struct io io;
  103. X    list o_list;  /* List of objects in graph */
  104. X    struct axes a;
  105. X    struct state s;
  106. X};
  107. X
  108. X/* Open font name, in pts points (use graph scale). Takes nearest size */
  109. Xstruct TextFont *open_font(struct graph *g, char *name, int pts, int style, int
  110. X flags);
  111. X/* Convert size in inches to dots in selected output */
  112. Xint xinch2dots(struct graph *g, double x);
  113. Xint yinch2dots(struct graph *g, double y);
  114. X
  115. X/* objects */
  116. Xstruct object *add_object(struct graph *g, struct object *o);
  117. Xvoid remove_object(struct graph *g, struct object *o);
  118. Xvoid select_object(struct graph *g, struct object *o);
  119. Xvoid deselect(struct graph *g);
  120. X
  121. X/* User has used mouse, do any necessary housekeeping (move, select objects, et
  122. Xc) */
  123. Xvoid mouse_down(struct graph *g, WORD sx, WORD sy);
  124. Xvoid mouse_move(struct graph *g, WORD sx, WORD sy);
  125. Xvoid mouse_up(struct graph *g, WORD sx, WORD sy);
  126. X
  127. X/* Ask user to : */
  128. Xstruct object *choose_object(struct graph *g, char *op); /* Select object by na
  129. Xme */
  130. Xvoid enter_limits(struct graph *g); /* Define coord system */
  131. Xvoid enter_axes(struct graph *g);   /* Choose axes display options */
  132. X
  133. X/* Change graph: */
  134. Xint set_dpm(struct graph *g, int dpmx, int dpmy); /* set new scale (in dpm) */
  135. Xvoid set_thin(struct graph *g, struct RastPort *rp); /* Use thin lines */
  136. Xvoid set_pensize(struct graph *g, struct RastPort *rp, double ptsize); /* Use l
  137. Xines ptsize points wide */
  138. Xvoid set_mode(struct graph *g, int newmode); /* Select select/point mode */
  139. Xvoid set_scale(struct graph *g);      /* Window size has changed */
  140. Xvoid zoom_in(struct graph *g, double x0, double y0, double x1, double y1); /* S
  141. Xet new coord limits */
  142. Xvoid zoom_factor(struct graph *g, double factor); /* Zoom in by a factor */
  143. Xvoid center_graph(struct graph *g, double x, double y); /* Recenter around poin
  144. Xt */
  145. X
  146. X/* Output routines: */
  147. Xvoid draw_graph(struct graph *g, int allow_mes); /* Draw graph */
  148. Xvoid refresh_graph(struct graph *g, int allow_mes, struct Region *ref); /* Redr
  149. Xaw inside region ref only */
  150. Xstruct Region *full_refresh(struct graph *g); /* Return a region covering the w
  151. Xhole graph */
  152. Xvoid set_title(struct graph *g);   /* Change graph title */
  153. Xvoid prt_graph(struct graph *g);   /* Output graph to printer */
  154. Xvoid iff_todisk(struct graph *g);  /* Output graph as an ILBM file */
  155. X
  156. X/* Manipulate graphs : */
  157. Xstruct graph *load_graph(struct graph *from, FILE *f);
  158. Xint save_graph(struct graph *g, FILE *f);
  159. Xstruct graph *new_graph(struct graph *from); /* from allows you to display mess
  160. Xages ... (NULL if none) */
  161. Xvoid delete_graph(struct graph *g);
  162. X
  163. X/* Global init/cleanup. Must be called */
  164. Xint init_grph(void);
  165. Xvoid cleanup_grph(void);
  166. X
  167. X#endif
  168. X
  169. SHAR_EOF
  170. echo "extracting label.c"
  171. sed 's/^X//' << \SHAR_EOF > label.c
  172. X/*
  173. X *                 GRAPH, Version 1.00 - 4 August 1989
  174. X *
  175. X *            Copyright 1989, David Gay. All Rights Reserved.
  176. X *            This software is freely redistrubatable.
  177. X */
  178. X
  179. X#include <exec/types.h>
  180. X#include <intuition/intuition.h>
  181. X#include <graphics/text.h>
  182. X#include <string.h>
  183. X#include <limits.h>
  184. X
  185. X#include "object.h"
  186. X#include "object/default.h"
  187. X#include "file.h"
  188. X#include "graph.h"
  189. X#include "uio.h"
  190. X#include "coords.h"
  191. X#include "grph.h"
  192. X#include "user/gadgets.h"
  193. X#include "graphics.h"
  194. X#include "tracker.h"
  195. X
  196. X#include <proto/exec.h>
  197. X#include <proto/intuition.h>
  198. X#include <proto/graphics.h>
  199. X
  200. X#define LABELLEN 256
  201. X#define LABELHEIGHT 10
  202. X#define LABELFONT "topaz.font"
  203. X#define FONTLIST 2
  204. X
  205. X/* The various justification possibilities */
  206. Xenum justify { top, centre, bottom };
  207. X
  208. X/* (private) class label, inherits from object */
  209. Xstruct label
  210. X{
  211. X    struct object o;
  212. X    char text[LABELLEN]; /* What to display, \ for newlines */
  213. X    BYTE colour;
  214. X    char fname[FONTLEN]; /* font name */
  215. X    int fheight;         /* font height */
  216. X    double x, y;         /* text position */
  217. X    double dx, dy;       /* offset from position, in inches */
  218. X    enum justify jx, jy; /* justification (x & y axes) */
  219. X
  220. X    char selected;
  221. X    /* Temp, etc vars */
  222. X    char broken[LABELLEN];   /* Text, separated into lines (separated by NULLs)
  223. X */
  224. X    int nblines;             /* number of lines */
  225. X    struct Rectangle extent; /* Size of rectangle taken by text */
  226. X    int bw, bh;              /* Size of bitmap (for moving) */
  227. X    struct Rectangle lims;   /* Rectangle taken up on screen */
  228. X    int x0, y0;              /* x & y in screen coords (wthout ddx, ddy) */
  229. X    struct TextFont *font, *newfont; /* the font (newfont for inform/confirm) *
  230. X/
  231. X    double oldx, oldy;       /* position before move */
  232. X    int ddx, ddy;            /* dx, dy in pixels */
  233. X    struct Region *ref;
  234. X    struct RastPort bkgd;    /* Rastport & bitmap for moves */
  235. X    struct BitMap bkgd_bm;
  236. X};
  237. X
  238. X/*-------------------------------------------------------------------------*/
  239. X/*                       label class implementation                        */
  240. X/*-------------------------------------------------------------------------*/
  241. X
  242. X/* Allocates bitmap for saving background while moving */
  243. X/* Assumes 2 bit planes */
  244. Xstatic int alloc_bkgd_label(struct label *this)
  245. X{
  246. X    BYTE *data;
  247. X
  248. X    if (data = AllocMem(2 * RASSIZE(this->bw, this->bh), MEMF_CHIP))
  249. X    {
  250. X        InitBitMap(&this->bkgd_bm, 2, this->bw, this->bh);
  251. X        this->bkgd_bm.Planes[0] = (PLANEPTR)data;
  252. X        this->bkgd_bm.Planes[1] = (PLANEPTR)(data + RASSIZE(this->bw, this->bh)
  253. X);
  254. X        InitRastPort(&this->bkgd);
  255. X        this->bkgd.BitMap = &this->bkgd_bm;
  256. X    }
  257. X    return data != 0;
  258. X}
  259. X
  260. X/* Frees bitmap alloced above */
  261. Xstatic void free_bkgd_label(struct label *this)
  262. X{
  263. X    FreeMem(this->bkgd_bm.Planes[0], 2 * RASSIZE(this->bw, this->bh));
  264. X}
  265. X
  266. X/* Save scrren background into temp space */
  267. Xstatic void save_bkgd_label(struct label *this)
  268. X{
  269. X    ClipBlit(this->o.g->io.rw->rp, this->lims.MinX, this->lims.MinY, &this->bkg
  270. Xd, 0, 0, this->bw, this->bh, 0xc0);
  271. X}
  272. X
  273. X/* Copies saved background back to the screen */
  274. Xstatic void restore_bkgd_label(struct label *this)
  275. X{
  276. X    ClipBlit(&this->bkgd, 0, 0, this->o.g->io.rw->rp, this->lims.MinX, this->li
  277. Xms.MinY, this->bw, this->bh, 0xc0);
  278. X}
  279. X
  280. X/* Do all the precalculations */
  281. Xstatic void setup_label(struct label *this)
  282. X{
  283. X    struct TextFont *font = this->font;
  284. X    char *srch, *nl;
  285. X
  286. X    this->ddx = xinch2dots(this->o.g, this->dx);
  287. X    this->ddy = yinch2dots(this->o.g, this->dy);
  288. X
  289. X    /* Break up label & calculate rectangle used */
  290. X    srch = strcpy(this->broken, this->text);
  291. X    this->nblines = 0;
  292. X    this->extent.MaxX = 0;
  293. X    this->extent.MinX = INT_MAX;
  294. X    do
  295. X    {
  296. X        struct TextExtent te;
  297. X
  298. X        nl = strchr(srch, '\\');
  299. X
  300. X        if (nl && *(nl + 1) == '\\') /* add single slash */
  301. X            movmem(nl + 1, nl, LABELLEN - (nl - this->broken) - 1);
  302. X        else
  303. X        {
  304. X            this->nblines++;
  305. X            if (nl) *nl = '\0';
  306. X            /* Check space for this line */
  307. X            TextExtent(srch, font, &te);
  308. X            if (te.te_Extent.MaxX > this->extent.MaxX) this->extent.MaxX = te.t
  309. Xe_Extent.MaxX;
  310. X            if (te.te_Extent.MinX < this->extent.MinX) this->extent.MinX = te.t
  311. Xe_Extent.MinX;
  312. X        }
  313. X        srch = nl + 1;
  314. X    } while (nl);
  315. X
  316. X    this->extent.MinY = 0;
  317. X    this->extent.MaxY = this->nblines * font->tf_YSize;
  318. X    this->bw = this->extent.MaxX - this->extent.MinX + 1;
  319. X    this->bh = this->extent.MaxY - this->extent.MinY + 1;
  320. X}
  321. X
  322. X/* Work out rectangle used by text */
  323. Xstatic void calc_rect(struct label *this)
  324. X{
  325. X    struct graph *g = this->o.g;
  326. X    struct RWindow *rw = g->io.rw;
  327. X    int delta, x0, y0;
  328. X
  329. X    /* Find origin */
  330. X    /* Default */
  331. X    x0 = (this->x0 = ftol(rw->sx(rw, this->x))) + this->ddx;
  332. X    y0 = (this->y0 = ftol(rw->sy(rw, this->y))) + this->ddy;
  333. X
  334. X    /* Adjust for justification */
  335. X    switch (this->jx)
  336. X    {
  337. X        case centre:
  338. X            x0 -= this->bw / 2;
  339. X            break;
  340. X        case bottom: /* right */
  341. X            x0 -= this->bw;
  342. X            break;
  343. X    }
  344. X    switch (this->jy)
  345. X    {
  346. X        case centre:
  347. X            y0 -= this->bh / 2;
  348. X            break;
  349. X        case bottom: /* right */
  350. X            y0 -= this->bh;
  351. X            break;
  352. X    }
  353. X    /* Extent defines actual rectangle */
  354. X    this->lims.MinX = x0 + this->extent.MinX;
  355. X    this->lims.MaxX = x0 + this->extent.MaxX;
  356. X    this->lims.MinY = y0 + this->extent.MinY;
  357. X    this->lims.MaxY = y0 + this->extent.MaxY;
  358. X
  359. X    /* Make sure that it stays visible */
  360. X    /* Could one reduce the number of flops ? */
  361. X    /* Idea: Generalise inform/confirm */
  362. X    if ((delta = ftol(rw->sx(rw, g->a.x.min)) - this->lims.MinX) > 0 ||
  363. X        (delta = ftol(rw->sx(rw, g->a.x.max)) - this->lims.MaxX) < 0)
  364. X    {
  365. X        this->x0 += delta;
  366. X        this->lims.MinX += delta;
  367. X        this->lims.MaxX += delta;
  368. X    }
  369. X    if ((delta = ftol(rw->sy(rw, g->a.y.max)) - this->lims.MinY) > 0 ||
  370. X        (delta = ftol(rw->sy(rw, g->a.y.min)) - this->lims.MaxY) < 0)
  371. X    {
  372. X        this->y0 += delta;
  373. X        this->lims.MinY += delta;
  374. X        this->lims.MaxY += delta;
  375. X    }
  376. X}
  377. X
  378. X/* Add the current position to the region */
  379. Xstatic void add_region(struct label *this)
  380. X{
  381. X    if (!this->ref) this->ref = NewRegion();
  382. X    if (this->ref && !OrRectRegion(this->ref, &this->lims))
  383. X    {
  384. X        DisposeRegion(this->ref);
  385. X        this->ref = NULL;
  386. X    }
  387. X    if (!this->ref) nomem(this->o.g->io.win);
  388. X}
  389. X
  390. X/* Were we clicked on ? */
  391. Xstatic int down_label(struct label *this)
  392. X{
  393. X    struct graph *g = this->o.g;
  394. X    WORD sx = ftol(g->io.rw->sx(g->io.rw, g->s.x));
  395. X    WORD sy = ftol(g->io.rw->sy(g->io.rw, g->s.y));
  396. X    int inside;
  397. X
  398. X    calc_rect(this);
  399. X    inside = sx >= this->lims.MinX && sx <= this->lims.MaxX &&
  400. X             sy >= this->lims.MinY && sy <= this->lims.MaxY;
  401. X    if (inside)
  402. X    {
  403. X        /* Setup internal info for move */
  404. X        this->o.mx = sx - this->x0;
  405. X        this->o.my = sy - this->y0;
  406. X        if (alloc_bkgd_label(this))
  407. X        {
  408. X            save_bkgd_label(this);
  409. X            if (this->selected)
  410. X            {
  411. X                SetDrMd(&this->bkgd, COMPLEMENT);
  412. X                RectFill(&this->bkgd, 0, 0, this->bw - 1, this->bh - 1);
  413. X            }
  414. X            this->ref = NULL;
  415. X            add_region(this); /* Original pos. will probably need refreshing */
  416. X     
  417. X            this->oldx = this->x; this->oldy = this->y;
  418. X        }
  419. X        else /* failed, no mem */
  420. X        {
  421. X            nomem(this->o.g->io.win);
  422. X            inside = FALSE;
  423. X        }
  424. X    }
  425. X    return inside;
  426. X}
  427. X
  428. X/* Reverse label's rectangle (eg for selection) */
  429. Xstatic void reverse_label(struct label *this)
  430. X{
  431. X    struct RastPort *rp = this->o.g->io.rw->rp;
  432. X
  433. X    SetDrMd(rp, COMPLEMENT);
  434. X    RectFill(rp, this->lims.MinX, this->lims.MinY, this->lims.MaxX, this->lims.
  435. XMaxY);
  436. X}
  437. X
  438. X/* Draw label */
  439. Xstatic void draw_label(struct label *this, int allow_mes)
  440. X{
  441. X    struct graph *g = this->o.g;
  442. X    struct RastPort *rp = g->io.rw->rp;
  443. X    char *str;
  444. X    int i;
  445. X
  446. X    calc_rect(this);
  447. X    SetAPen(rp, this->colour);
  448. X    SetDrMd(rp, JAM1);
  449. X    SetFont(rp, this->font);
  450. X
  451. X    /* Draw all the lines of text */
  452. X    Move(rp, this->lims.MinX - this->extent.MinX, this->lims.MinY - this->exten
  453. Xt.MinY + this->font->tf_Baseline);
  454. X    for (str = this->broken, i = this->nblines; i; i--)
  455. X    {
  456. X        int l = strlen(str);
  457. X
  458. X        Text(rp, str, l);
  459. X        Move(rp, this->lims.MinX - this->extent.MinX, rp->cp_y + this->font->tf
  460. X_YSize);
  461. X
  462. X        str += l + 1; /* Onto next string */
  463. X    }
  464. X
  465. X    if (this->selected) reverse_label(this);
  466. X}
  467. X
  468. X/* We're now selected */
  469. Xstatic void select_label(struct label *this)
  470. X{
  471. X    this->selected = TRUE;
  472. X    if (this->o.g->ok && this->o.g->io.rw)
  473. X    {
  474. X        calc_rect(this);
  475. X        reverse_label(this);
  476. X    }
  477. X}
  478. X
  479. X/* A quick walk around town ... */
  480. Xstatic void move_label(struct label *this)
  481. X{
  482. X    restore_bkgd_label(this); /* erase label */
  483. X    this->x = this->o.g->s.x;
  484. X    this->y = this->o.g->s.y;
  485. X    calc_rect(this);
  486. X    save_bkgd_label(this);    /* Save background */
  487. X    draw_label(this, TRUE);   /* & draw at new pos */
  488. X}
  489. X
  490. X/* Mouse buttonb released, refresh needed ? */
  491. Xstatic struct Region *up_label(struct label *this)
  492. X{
  493. X    restore_bkgd_label(this); /* Restore at last pos */
  494. X    this->x = this->o.g->s.x;
  495. X    this->y = this->o.g->s.y;
  496. X    calc_rect(this);
  497. X    free_bkgd_label(this);
  498. X    if (this->x != this->oldx || this->y != this->oldy) /* we moved */
  499. X    {
  500. X        add_region(this); /* Refresh at new pos */
  501. X        return this->ref;
  502. X    }
  503. X    else
  504. X    {
  505. X        draw_label(this, TRUE); /* Just redraw, no refresh needed */
  506. X        DisposeRegion(this->ref);
  507. X        return NULL;
  508. X    }
  509. X}
  510. X
  511. X/* End of selection, unhighlight */
  512. Xstatic struct Region *deselect_label(struct label *this)
  513. X{
  514. X    this->selected = FALSE;
  515. X    if (this->o.g->ok && this->o.g->io.rw)
  516. X    {
  517. X        calc_rect(this);
  518. X        reverse_label(this);
  519. X    }
  520. X    return NULL;
  521. X}
  522. X
  523. X/* Handle edit requester */
  524. Xint edit_handler(struct Gadget *gg, ULONG class, struct Requester *req, struct
  525. Xgraph *g)
  526. X{
  527. X    if (gg->GadgetID == FONTLIST) /* User played with font list */
  528. X    {
  529. X        if (ModifyList(gg, req, req->RWindow, class == GADGETUP) == 2)
  530. X        {
  531. X            /* Double click -> exit */
  532. X            EndRequest(req, req->RWindow);
  533. X            return TRUE;
  534. X        }
  535. X        return FALSE;
  536. X    }
  537. X    else return std_ghandler(gg, class, req, g);
  538. X}
  539. X
  540. X/* Allow user to edit us */
  541. Xstatic int edit_label(struct label *this, struct Region **ref)
  542. X{
  543. X    struct Requester *req;
  544. X    struct Memory *m;
  545. X    struct Gadget *gl = NULL;
  546. X    int ret = FALSE;
  547. X    char text[LABELLEN], dx[NBLEN], dy[NBLEN], x[NBLEN], y[NBLEN], fname[FONTLE
  548. XN], fheight[INTLEN], colour[INTLEN];
  549. X    struct Gadget *leftg, *ctrxg, *rightg, *topg, *ctryg, *bottomg;
  550. X
  551. X    this->ref = NULL;
  552. X
  553. X    /* Create requester */
  554. X    strcpy(text, this->text);
  555. X    double2str(dx, this->dx);
  556. X    double2str(dy, this->dy);
  557. X    double2str(x, this->x);
  558. X    double2str(y, this->y);
  559. X    strcpy(fname, this->fname);
  560. X    remfont(fname);
  561. X    int2str(fheight, this->fheight);
  562. X    int2str(colour, this->colour);
  563. X
  564. X    if ((m = NewMemory()) &&
  565. X        (req = InitReq(50, 15, 395, 166, m)) &&
  566. X        SetReqBorder(req, 1, m) &&
  567. X        AddIntuiText(&req->ReqText, "Edit Label", 158, 6, m) &&
  568. X        AddText(&gl, 0, "Text ", FALSE, text, LABELLEN, TRUE, 0, RELVERIFY, 49,
  569. X 20, 335, 10, TRUE, m) &&
  570. X        AddText(&gl, 0, "X = ", FALSE, x, NBLEN, TRUE, 0, RELVERIFY, 43, 40, 56
  571. X, 10, TRUE, m) &&
  572. X        AddText(&gl, 0, "dX = ", FALSE, dx, NBLEN, TRUE, 0, RELVERIFY, 147, 40,
  573. X 56, 10, TRUE, m) &&
  574. X        (leftg = AddRadio(&gl, 0, "left", TRUE, SELECTED * (this->jx == top), R
  575. XELVERIFY, 16 + 32, 210, 40, 10, 10, m)) &&
  576. X        (ctrxg = AddRadio(&gl, 0, "centre", TRUE, SELECTED * (this->jx == centr
  577. Xe), RELVERIFY, 8 + 32, 260, 40, 10, 10, m)) &&
  578. X        (rightg = AddRadio(&gl, 0, "right", TRUE, SELECTED * (this->jx == botto
  579. Xm), RELVERIFY, 16 + 8, 326, 40, 10, 10, m)) &&
  580. X        AddText(&gl, 0, "Y = ", FALSE, y, NBLEN, TRUE, 0, RELVERIFY, 43, 60, 56
  581. X, 10, TRUE, m) &&
  582. X        AddText(&gl, 0, "dY = ", FALSE, dy, NBLEN, TRUE, 0, RELVERIFY, 147, 60,
  583. X 56, 10, TRUE, m) &&
  584. X        (topg = AddRadio(&gl, 0, "top", TRUE, SELECTED * (this->jy == top), REL
  585. XVERIFY, 512 + 1024, 210, 60, 10, 10, m)) &&
  586. X        (ctryg = AddRadio(&gl, 0, "centre", TRUE, SELECTED * (this->jy == centr
  587. Xe), RELVERIFY, 256 + 1024, 260, 60, 10, 10, m)) &&
  588. X        (bottomg = AddRadio(&gl, 0, "bottom", TRUE, SELECTED * (this->jy == bot
  589. Xtom), RELVERIFY, 256 + 512, 326, 60, 10, 10, m)) &&
  590. X        AddText(&gl, 0, "Colour ", FALSE, colour, INTLEN, TRUE, 0, RELVERIFY, 2
  591. X36, 80, 32, 10, TRUE, m) &&
  592. X        AddText(&gl, 0, "Size ", FALSE, fheight, INTLEN, TRUE, 0, RELVERIFY, 22
  593. X0, 150, 32, 10, TRUE, m) &&
  594. X        AddList(&gl, FONTLIST, "Font", &flist, fname, FONTLEN, 0, RELVERIFY, 11
  595. X, 80, 160, 80, TRUE, m) &&
  596. X        AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 255, 100, 65, 15, FAL
  597. XSE, m) &&
  598. X        AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 255, 130, 65, 15
  599. X, FALSE, m))
  600. X    {
  601. X        SetReqGadgets(req, gl);
  602. X        if (ret = DoRequest(req, this->o.g, edit_handler) && *stpblk(text) != '
  603. X\0')
  604. X        {
  605. X            /* Update label */
  606. X            double new;
  607. X            int fh;
  608. X            struct TextFont *newfont;
  609. X
  610. X            add_region(this); /* Refresh needed at old pos */
  611. X
  612. X            /* New justification, etc */
  613. X            if ((this->colour = str2int(colour)) == INOVAL) this->colour = 1;
  614. X            strcpy(this->text, text);
  615. X            if ((new = str2double(x)) != NOVAL) this->x = new;
  616. X            if ((new = str2double(y)) != NOVAL) this->y = new;
  617. X            if ((this->dx = str2double(dx)) == NOVAL) this->dx = 0.0;
  618. X            if ((this->dy = str2double(dy)) == NOVAL) this->dy = 0.0;
  619. X
  620. X            if (leftg->Flags & SELECTED) this->jx = top;
  621. X            else if (ctrxg->Flags & SELECTED) this->jx = centre;
  622. X            else this->jx = bottom;
  623. X
  624. X            if (topg->Flags & SELECTED) this->jy = top;
  625. X            else if (ctryg->Flags & SELECTED) this->jy = centre;
  626. X            else this->jy = bottom;
  627. X
  628. X            /* Check font */
  629. X            addfont(fname);
  630. X            if ((fh = str2int(fheight)) == INOVAL || fh <= 0) fh = LABELHEIGHT;
  631. X     
  632. X            if (newfont = open_font(this->o.g, fname, fh, 0, 0))
  633. X            {
  634. X                strcpy(this->fname, fname);
  635. X                this->fheight = fh;
  636. X                CloseFont(this->font);
  637. X                this->font = newfont;
  638. X            }
  639. X            else message(this->o.g, "Invalid font specified", (char *)NULL);
  640. X
  641. X            /* Do precalculation */
  642. X            setup_label(this);
  643. X            calc_rect(this);
  644. X            add_region(this); /* New position needs refreshing */
  645. X        }
  646. X    }
  647. X    Free(m);
  648. X    *ref = this->ref;
  649. X    return ret;
  650. X}
  651. X
  652. X/* No vsriables used in labels */
  653. Xint var_change_label(struct label *this, char *name)
  654. X{
  655. X    return FALSE;
  656. X}
  657. X
  658. X/* Confirm changes made */
  659. Xstatic void confirm_label(struct label *this, int ok)
  660. X{
  661. X    if (ok)
  662. X    {
  663. X        CloseFont(this->font);
  664. X        this->font = this->newfont;
  665. X        setup_label(this);
  666. X    }
  667. X    else CloseFont(this->newfont); /* failed */
  668. X}
  669. X
  670. X/* Resolution has changed */
  671. Xstatic int inform_label(struct label *this, int ok)
  672. X{
  673. X    if (this->newfont = open_font(this->o.g, this->fname, this->fheight, 0, 0))
  674. X     
  675. X        return TRUE;
  676. X
  677. X    message(this->o.g, "Couldn't open font", (char *)NULL);
  678. X    return FALSE;
  679. X
  680. X}
  681. X
  682. X/* Write label to file */
  683. Xstatic int save_label(struct label *this, FILE *f)
  684. X{
  685. X    short tag = LABEL_TAG;
  686. X    short end = LABEL_END;
  687. X
  688. X    return WRITE(f, tag) &&
  689. X           WRITE(f, this->text) &&
  690. X           WRITE(f, this->colour) &&
  691. X           WRITE(f, this->fname) &&
  692. X           WRITE(f, this->fheight) &&
  693. X           WRITE(f, this->x) &&
  694. X           WRITE(f, this->y) &&
  695. X           WRITE(f, this->dx) &&
  696. X           WRITE(f, this->dy) &&
  697. X           WRITE(f, end);
  698. X}
  699. X
  700. X/* free label */
  701. Xstatic struct Region *delete_label(struct label *this)
  702. X{
  703. X    struct Region *ref;
  704. X
  705. X    /* Label's position will need refreshing */
  706. X    this->ref = NULL;
  707. X    if (this->o.g->ok && this->o.g->io.rw) add_region(this);
  708. X    ref = this->ref;
  709. X
  710. X    if (this->font) CloseFont(this->font);
  711. X    FreeMem(this, sizeof(struct label));
  712. X
  713. X    return ref;
  714. X}
  715. X
  716. X/* Initialise label structure */
  717. Xstatic struct label *make_label(struct graph *g)
  718. X{
  719. X    struct label *this = AllocMem(sizeof(struct label), 0L);
  720. X    const static struct label def_l = {
  721. X        {
  722. X            { NULL },
  723. X            NULL, "", TRUE, 0, 0,
  724. X            (void *)delete_label, (void *)select_label, (void *)deselect_label,
  725. X     
  726. X            (void *)down_label, (void *)move_label, (void *)up_label,
  727. X            (void *)edit_label, (void *)draw_label, (void *)notdone,
  728. X            (void *)notdone, (void *)var_change_label, (void *)save_label,
  729. X            (void *)inform_label, (void *)confirm_label
  730. X        },
  731. X        "", 1, LABELFONT, LABELHEIGHT, NOVAL, NOVAL, 0.0, 0.0, FALSE
  732. X    };
  733. X
  734. X    if (this)
  735. X    {
  736. X        *this = def_l;
  737. X        this->o.g = g;
  738. X        /* Default font *must* be there */
  739. X        if (this->font = open_font(g, LABELFONT, LABELHEIGHT, 0, 0))
  740. X        {
  741. X            return this;
  742. X        }
  743. X        else
  744. X            message(g, "Couldn't open font", (char *)NULL);
  745. X        FreeMem(this, sizeof(struct label));
  746. X    }
  747. X    else
  748. X        message(g, "No memory !", (char *)NULL);
  749. X    return NULL;
  750. X}
  751. X
  752. X/* Load label from file */
  753. Xstruct label *load_label(struct graph *g, FILE *f)
  754. X{
  755. X    struct label *this = make_label(g);
  756. X
  757. X    if (this)
  758. X    {
  759. X        short tag;
  760. X
  761. X        if (READ(f, this->text) &&
  762. X            READ(f, this->colour) &&
  763. X            READ(f, this->fname) &&
  764. X            READ(f, this->fheight) &&
  765. X            READ(f, this->x) &&
  766. X            READ(f, this->y) &&
  767. X            READ(f, this->dx) &&
  768. X            READ(f, this->dy) &&
  769. X            READ(f, tag) &&
  770. X            tag == LABEL_END)
  771. X        {
  772. X            struct TextFont *newfont;
  773. X
  774. X            if (newfont = open_font(this->o.g, this->fname, this->fheight, 0, 0
  775. X))
  776. X            {
  777. X                CloseFont(this->font);
  778. X                this->font = newfont;
  779. X            }
  780. X            else /* Lack of font isn't drastic */
  781. X            {
  782. X                message(g, "No such font available", this->fname, (char *)NULL)
  783. X;
  784. X                strcpy(this->fname, LABELFONT);
  785. X            }
  786. X            setup_label(this);
  787. X            return this;
  788. X        }
  789. X        delete_label(this);
  790. X    }
  791. X    return NULL;
  792. X}
  793. X
  794. X/* Create a new label, at pos. (x,y). Asks user for text */
  795. Xstruct label *new_label(struct graph *g, double x, double y)
  796. X{
  797. X    struct label *this = make_label(g);
  798. X
  799. X    if (this)
  800. X    {
  801. X        /* Create requester */
  802. X        struct Requester *req;
  803. X        struct Memory *m;
  804. X        struct Gadget *gl = NULL;
  805. X        int ret = FALSE;
  806. X
  807. X        this->x = x;
  808. X        this->y = y;
  809. X
  810. X        if ((m = NewMemory()) &&
  811. X            (req = InitReq(50, 20, 160, 65, m)) &&
  812. X            SetReqBorder(req, 1, m) &&
  813. X            AddIntuiText(&req->ReqText, "Add Label", 44, 6, m) &&
  814. X            AddText(&gl, TRUE, "Text ", FALSE, this->text, LABELLEN, TRUE, 0, R
  815. XELVERIFY | ENDGADGET, 49, 20, 100, 10, TRUE, m) &&
  816. X            AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 8, 40, 65, 15, FA
  817. XLSE, m) &&
  818. X            AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 88, 40, 65,
  819. X15, FALSE, m))
  820. X        {
  821. X            SetReqGadgets(req, gl);
  822. X            if (ret = DoRequest(req, g, std_ghandler) && *stpblk(this->text) !=
  823. X '\0')
  824. X            {
  825. X                /* Create it */
  826. X                setup_label(this);
  827. X                if (g->ok && g->io.rw) draw_label(this, TRUE);
  828. X                Free(m);
  829. X                return this;
  830. X            }
  831. X        }
  832. X        Free(m);
  833. X        delete_label(this);
  834. X    }
  835. X    else
  836. X        message(g, "No memory !", (char *)NULL);
  837. X    return NULL;
  838. X}
  839. X
  840. SHAR_EOF
  841. echo "extracting list.c"
  842. sed 's/^X//' << \SHAR_EOF > list.c
  843. X/*
  844. X *                 GRAPH, Version 1.00 - 4 August 1989
  845. X *
  846. X *            Copyright 1989, David Gay. All Rights Reserved.
  847. X *            This software is freely redistrubatable.
  848. X */
  849. X
  850. X#include <exec/types.h>
  851. X#include <stddef.h>
  852. X#include "list.h"
  853. X#include "tracker.h"
  854. X
  855. X/* Free all elements in list (each of size size) */
  856. Xvoid free_list(list *l, size_t size)
  857. X{
  858. X    node *scan, *next;
  859. X
  860. X    for (scan = first(l); next = succ(scan); scan = next)
  861. X        FreeMem(scan, size);
  862. X
  863. X    /* Be safe */
  864. X    new_list(l);
  865. X}
  866. X
  867. SHAR_EOF
  868. echo "extracting list.h"
  869. sed 's/^X//' << \SHAR_EOF > list.h
  870. X/*
  871. X *                 GRAPH, Version 1.00 - 4 August 1989
  872. X *
  873. X *            Copyright 1989, David Gay. All Rights Reserved.
  874. X *            This software is freely redistrubatable.
  875. X */
  876. X
  877. X/* Simplify and "genericize" list operations */
  878. X#ifndef LIST_H
  879. X#define LIST_H
  880. X
  881. X#include <exec/nodes.h>
  882. X#include <exec/lists.h>
  883. X#include <stddef.h>
  884. X
  885. X/* The standard list elements */
  886. Xtypedef struct MinList list;
  887. Xtypedef struct MinNode node;
  888. Xtypedef struct List tlist; /* Typed list */
  889. Xtypedef struct Node tnode; /* Typed (&named) node */
  890. X
  891. X#define new_list(list) NewList((tlist *)(list))
  892. X
  893. X#define add_head(list, node) AddHead((tlist *)(list), (tnode *)(node))
  894. X#define add_tail(list, node) AddTail((tlist *)(list), (tnode *)(node))
  895. X#define rem_head(list) (void *)RemHead((tlist *)(list))
  896. X#define rem_tail(list) (void *)RemTail((tlist *)(list))
  897. X
  898. X#define remove(node) Remove((tnode *)(node))
  899. X#define insert(list, node, pos) Insert((tlist *)(list), (tnode *)(node), (tnode
  900. X *)(pos))
  901. X
  902. X#define first(list) ((void *)((tlist *)(list))->lh_Head)
  903. X#define last(list) ((void *)((tlist *)(list))->lh_Tail)
  904. X#define empty(list) (((tlist *)(list))->lh_TailPred == (tnode *)(list))
  905. X
  906. X#define succ(node) (void *)(((tnode *)(node))->ln_Succ)
  907. X#define pred(node) (void *)(((tnode *)(node))->ln_Pred)
  908. X
  909. X#define alloc_node(size) AllocMem((size), 0L)
  910. X
  911. X/* Free all elements of a homogeneous list */
  912. Xvoid free_list(list *l, size_t size);
  913. X
  914. X#endif
  915. X
  916. SHAR_EOF
  917. echo "extracting lmkfile"
  918. sed 's/^X//' << \SHAR_EOF > lmkfile
  919. XFLAGS = -Hsmall.sym -csf -d3 -v -oo/
  920. XINCS = object.h uio.h list.h grph.h coords.h graph.h
  921. X
  922. X.c.o:
  923. X    lc $(FLAGS) $*
  924. X
  925. Xgraph: graph.d
  926. X    blink from graph.d to graph nodebug
  927. X
  928. Xgraph.d: small.sym o/graph.o o/coords.o o/grph.o o/uio.o o/tracker.o o/list.o o
  929. X/pos.o o/label.o o/f_of_x.o o/x_y.o o/r_of_t.o o/function.o o/default.o o/r_t.o
  930. Xo/graphics.o o/gadgets.o
  931. X    blink with lnk
  932. X
  933. Xsmall.sym: smallsym.c
  934. X    lc -ph -osmall.sym smallsym.c
  935. X
  936. Xo/gadgets.o: gadgets/gadgets.c user/gadgets.h
  937. X
  938. Xo/graphics.o: graphics.c graphics.h
  939. X
  940. Xo/graph.o: graph.c $(INCS)
  941. X
  942. Xo/grph.o: grph.c $(INCS) graphics.h
  943. X
  944. Xo/uio.o: uio.c $(INCS)
  945. X
  946. Xo/coords.o: coords.c coords.h
  947. X
  948. Xo/list.o: list.c list.h
  949. X
  950. Xo/default.o: object/default.c object/default.h $(INCS)
  951. X
  952. Xo/pos.o: object/pos.c object/default.h $(INCS)
  953. X
  954. Xo/label.o: object/label.c object/default.h $(INCS) graphics.h
  955. X
  956. Xo/function.o: object/function.c object/function.h object/default.h $(INCS)
  957. X
  958. Xo/f_of_x.o: object/f_of_x.c object/function.h object/default.h $(INCS)
  959. X
  960. Xo/x_y.o: object/x_y.c object/function.h object/default.h $(INCS)
  961. X
  962. Xo/r_of_t.o: object/r_of_t.c object/function.h object/default.h $(INCS)
  963. X
  964. Xo/r_t.o: object/r_t.c object/function.h object/default.h $(INCS)
  965. X
  966. Xo/tracker.o: divers/tracker.c tracker.h
  967. X    lc -v -O -m1t -oo/ divers/tracker
  968. X
  969. SHAR_EOF
  970. echo "extracting lmko"
  971. sed 's/^X//' << \SHAR_EOF > lmko
  972. XFLAGS = -Hsmall.sym -csf -O -v -ooO/
  973. XINCS = object.h uio.h list.h grph.h coords.h graph.h
  974. X
  975. X.c.o:
  976. X    lc $(FLAGS) $*
  977. X
  978. Xgraph: small.sym oO/graph.o oO/coords.o oO/grph.o oO/uio.o oO/list.o oO/pos.o o
  979. XO/label.o oO/f_of_x.o oO/x_y.o oO/r_of_t.o oO/function.o oO/default.o oO/r_t.o o
  980. XO/graphics.o oO/gadgets.o
  981. X    blink with lnkO
  982. X
  983. Xsmall.sym: smallsym.c
  984. X    lc -ph -osmall.sym smallsym.c
  985. X
  986. XoO/gadgets.o: gadgets/gadgets.c user/gadgets.h
  987. X
  988. XoO/graphics.o: graphics.c graphics.h
  989. X
  990. XoO/graph.o: graph.c $(INCS)
  991. X
  992. XoO/grph.o: grph.c $(INCS) graphics.h
  993. X
  994. XoO/uio.o: uio.c $(INCS)
  995. X
  996. XoO/coords.o: coords.c coords.h
  997. X
  998. XoO/list.o: list.c list.h
  999. X
  1000. XoO/default.o: object/default.c object/default.h $(INCS)
  1001. X
  1002. XoO/pos.o: object/pos.c object/default.h $(INCS)
  1003. X
  1004. XoO/label.o: object/label.c object/default.h $(INCS) graphics.h
  1005. X
  1006. XoO/function.o: object/function.c object/function.h object/default.h $(INCS)
  1007. X
  1008. XoO/f_of_x.o: object/f_of_x.c object/function.h object/default.h $(INCS)
  1009. X
  1010. XoO/x_y.o: object/x_y.c object/function.h object/default.h $(INCS)
  1011. X
  1012. XoO/r_of_t.o: object/r_of_t.c object/function.h object/default.h $(INCS)
  1013. X
  1014. XoO/r_t.o: object/r_t.c object/function.h object/default.h $(INCS)
  1015. X
  1016. SHAR_EOF
  1017. echo "extracting lnk"
  1018. sed 's/^X//' << \SHAR_EOF > lnk
  1019. XFROM LIB:c.o+o/graph.o+o/coords.o+o/uio.o+o/grph.o+o/tracker.o+o/list.o+o/gadge
  1020. Xts.o+o/pos.o+o/label.o+o/f_of_x.o+o/x_y.o+o/r_of_t.o+o/function.o+o/default.o+o/
  1021. Xr_t.o+o/graphics.o
  1022. XTO graph.d
  1023. XLIB lib:eval.lib+lib:lcmieee.lib+lib:lcm.lib+LIB:lc.lib+LIB:amiga.lib
  1024. XADDSYM
  1025. XVERBOSE
  1026. XBATCH
  1027. Xsc
  1028. X
  1029. SHAR_EOF
  1030. echo "extracting lnko"
  1031. sed 's/^X//' << \SHAR_EOF > lnko
  1032. Xfrom lib:c.o oO/graphics.o oO/coords.o oO/graph.o oO/grph.o oO/uio.o oO/gadgets
  1033. X.o oO/label.o oO/function.o oO/f_of_x.o oO/x_y.o oO/r_t.o oO/r_of_t.o oO/list.o
  1034. X oO/default.o oO/pos.o
  1035. XTO graph
  1036. XLIB lib:eval.lib+lib:lcmieee.lib+lib:lcm.lib+LIB:lc.lib+LIB:amiga.lib
  1037. XNODEBUG
  1038. XVERBOSE
  1039. XBATCH
  1040. Xsc
  1041. SHAR_EOF
  1042. echo "extracting make.shar"
  1043. sed 's/^X//' << \SHAR_EOF > make.shar
  1044. Xshar >graph.sh1 -p X README coords.c coords.h default.c default.h file.h functi
  1045. Xon.c +
  1046. X                function.h f_of_x.c gadgets.c
  1047. Xshar >graph.sh2 -p X gadgets.h graph.c graph.doc graph.h graphics.c graphics.h
  1048. Xshar >graph.sh3 -p X grph.c grph.h label.c
  1049. Xshar >graph.sh4 -p X list.c list.h lmkfile lmkO lnk lnkO mv2dir object.guidelin
  1050. Xes +
  1051. X                object.h pos.c r_of_t.c r_t.c smallsym.c tracker.c tracker.h
  1052. Xshar >graph.sh5 -p X uio.c uio.h x_y.c tracker.README make.shar
  1053. SHAR_EOF
  1054. echo "extracting mv2dir"
  1055. sed 's/^X//' << \SHAR_EOF > mv2dir
  1056. Xmakedir o
  1057. Xmakedir oO
  1058. Xmakedir gadgets
  1059. Xmakedir user
  1060. Xmakedir object
  1061. Xmakedir divers
  1062. Xrename gadgets.h user/gadgets.h
  1063. Xrename gadgets.c gadgets/gadgets.c
  1064. Xrename default.c object/default.c
  1065. Xrename default.h object/default.h
  1066. Xrename f_of_x.c object/f_of_x.c
  1067. Xrename function.c object/function.c
  1068. Xrename function.h object/function.h
  1069. Xrename label.c object/label.c
  1070. Xrename pos.c object/pos.c
  1071. Xrename r_of_t.c object/r_of_t.c
  1072. Xrename r_t.c object/r_t.c
  1073. Xrename x_y.c object/x_y.c
  1074. Xrename tracker.c divers
  1075. X
  1076. X
  1077. SHAR_EOF
  1078. echo "End of archive 5 (of 7)"
  1079. # if you want to concatenate archives, remove anything after this line
  1080. exit
  1081.